package com.zzg.datastructure.search;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author zhengzg
 * @Date 2022-09-15
 * @Version v1.0
 *
 * 二分查找：使用前提数组必须有序
 */
public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1, 8, 10, 89, 123, 1000, 1000};
        List<Integer> integerList = binarySearch(arr, 0, arr.length - 1, 1000);
        System.out.println(integerList);
    }

    public static List<Integer> binarySearch(int[] arr,int left,int right,int findVal) {

        // 此时说明没有找到数据
        if (left > right) {
            return new ArrayList<>();
        }

        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) {
            // 如果大于，说明数据在数组的右侧，此时向右递归
            return binarySearch(arr,mid + 1,right,findVal);
        } else if (findVal < midVal) {
            // 向左递归
            return binarySearch(arr,left,mid - 1,findVal);
        } else {
            // 直接找到
            /*
             * 在mid索引值，不要马上返回
             * 向mid索引值的左边，右边分别扫描，将所有满足 finaVal的元素的下标加入集合
             * 因为是有序集合，arr[mid]符合条件，则左右两边可能是符合条件的
             */

            List<Integer> redIndexList = new ArrayList<>();
            // 向左边扫描
            int temp = mid - 1;
            while (temp >= 0 && arr[temp] == findVal) {
                redIndexList.add(temp);
                temp--;
            }

            // 将原本找到的加入集合
            redIndexList.add(mid);

            //向右扫描
            temp = mid + 1;
            while (temp <= arr.length - 1 && arr[temp] == findVal) {
                redIndexList.add(temp);
                temp++;
            }
            return redIndexList;
        }
    }
}
